package cclub.demo.controller;

import cclub.demo.annotation.token.PassToken;
import cclub.demo.config.SecretConfig;
import cclub.demo.exception.InvalidParameterException;
import cclub.demo.exception.NoAuthException;
import cclub.demo.exception.SysException;
import cclub.demo.pojo.DO.userDO;
import cclub.demo.response.CodeEnum;
import cclub.demo.service.intf.userService;
import cclub.demo.service.secretService;
import cclub.demo.utils.jsonUtils;
import cclub.demo.utils.randUtils;
import cclub.demo.utils.regexUtils;
import com.cclub.inteface.model.messageTemplateBO;
import com.cclub.inteface.service.common.message;
import com.cclub.inteface.service.common.redisTools;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import cclub.demo.constant.cacheKey;

import javax.validation.constraints.Email;
import javax.validation.constraints.Pattern;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


@Slf4j
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    @Reference(version = "1.0.0")
    private redisTools redisTools;

    @Reference(version = "1.0.0")
    private message messageService;

    @NonNull
    private secretService secretService;

    @NonNull
    private userService userService;

    @NonNull
    private SecretConfig secretConfig;

    //用户在登录的时候发送验证码
    @PassToken
    @RequestMapping(value = "/sendPhoneCode",method = RequestMethod.POST)
    public Map sendPhoneCode(@RequestParam(value = "mobile") @Pattern(regexp = "1[3|4|5|7|8][0-9]{9}",message = "手机号格式不正确") String mobile){
        String randCode = randUtils.getRandCode(6);
        Map<String,String> map = new HashMap<String,String>(){{
            put("code",randCode);
        }};
        try {
            messageService.sendMessage(new ArrayList<messageTemplateBO>(){{
                add(new messageTemplateBO(mobile,"verifyCodeSMS", jsonUtils.getJson(map)));
            }});
            //把发送的验证码跟手机号写入缓存中
            redisTools.setCache(cacheKey.USER_LOGIN_CODE+mobile,randCode,cacheKey.USER_LOGIN_CACHE_TIME);
        }catch (Exception e){
            log.error("用户登录发送验证码失败mobile={},msg={}",mobile,e.getMessage());
            throw new SysException("发送短信验证码失败");
        }
        //把结果返回给前端,使用私钥将手机号加密生成签名sign
        String token = secretService.getSign(mobile);
        System.out.println(token);
        if(StringUtils.isEmpty(token)){
            throw new SysException();
        }
        return new HashMap<String,String>(){{
            put("token",token);
        }};
    }

    //校验用户登录时的手机验证码
    @PassToken
    @RequestMapping(value = "/checkLoginPhoneCode",method = RequestMethod.POST)
    public Map checkLoginPhoneCode(@RequestParam(value = "mobile") @Pattern(regexp = "1[3|4|5|7|8][0-9]{9}",message = "手机号格式不正确") String mobile,
                                    @RequestParam(value = "code") String code,
                                    @RequestParam(value = "sign") String sign){
        //进行sign验签
        boolean verify = secretService.checkSign(mobile,sign);
        //如果签名不符合就直接返回错误
        if(!verify){
            throw new NoAuthException("签名错误");
        }
        //判断code是否正确,正确后就登录成功,把code删除
        if(!redisTools.getCache(cacheKey.USER_LOGIN_CODE+mobile).equals(code)){
            throw new InvalidParameterException("验证码错误或者已失效");
        }
        //如果是新用户就插入用户信息
        userDO userDO = userService.registerUser(mobile);
        //根据生成的token将用户信息存储到redis中
        String userToken = secretService.getToken(userDO);
        if(StringUtils.isEmpty(userToken)){
            log.error("生成的token不能为空,token={},userDto={}",userToken,userDO.toString());
            throw new SysException();
        }
        redisTools.setCache(cacheKey.USER_INFO+userDO.getId(),userDO,cacheKey.USER_LOGIN_TIME);
        //把token,业务参数返回给前端
        return new HashMap<String,Object>(){{
            put("userInfo",userDO);
            put("token",userToken);
        }};
    }

    //获取用户信息
    @RequestMapping(value = "/getUserInfo", method = RequestMethod.POST)
    public userDO getUserInfo(@RequestParam(value = "user_id") int userId){
        userDO userDO = userService.getUserInfo(userId);
        if(userDO == null){
            throw new InvalidParameterException("userId查询不到对应的用户信息");
        }
        return userDO;
    }


    //用户退出登录
    @RequestMapping(value = "/signOut", method = RequestMethod.POST)
    public Map signOut(@RequestParam(value = "user_id") int userId) {
        redisTools.delCache(cacheKey.USER_INFO+userId);
        return new HashMap<String,Object>(){{
           put("status", CodeEnum.SUCCESS.getCode());
        }};
    }
}
